package com.emser.unc.client.presenter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

import com.emser.unc.client.CloudMobile;
import com.emser.unc.client.event.EditProductListEvent;
import com.emser.unc.client.event.GoBackEvent;
import com.emser.unc.client.helper.RPCCall;
import com.emser.unc.client.service.ProductService;
import com.emser.unc.client.service.ProductServiceAsync;
import com.emser.unc.serializable.ProductDTO;
import com.emser.unc.serializable.ResultDTO;
import com.emser.unc.serializable.SellerDTO;
import com.emser.unc.serializable.UserAccountDTO;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.RangeChangeEvent;

public class SellerProductsPresenter implements Presenter{
	private final Display display;
	private ProductServiceAsync productService;
	private UserAccountDTO userA;
	private SellerDTO seller;
	private SellerPresenter sellerPresenter;
	private int rangeStart;
	private SimpleEventBus eventBus;
	private ArrayList<String> cursors = new ArrayList<String>();
	private int pageNum;
	private String pageCursor;
	private int pageSize = CloudMobile.constants.pageSizeCP();
	
	public interface Display {	
	    Widget asWidget();
	    HasClickHandlers getSaveButton();
	    HasClickHandlers getGoBackButton();
	    MultiSelectionModel<ProductDTO> getSelectionModel();
		HasData<ProductDTO> getTable();
		void enableBtnSave(boolean enabled);
		void showBusyIndicator();
		void hideBusyIndicator();
		void setPage(int page);
		int getPage();
	  }
	public SellerProductsPresenter(UserAccountDTO user,EditProductListEvent event,SimpleEventBus eventBus,Display display){
		this.display = display;
		this.productService = GWT.create(ProductService.class);
		this.eventBus = eventBus;
		this.userA = user;
		this.sellerPresenter = event.getSp();
		this.seller = sellerPresenter.getSellerSelected();
		cursors.add(null);
		bind();
		updateRowCount();
	}
	
	private void bind() {
		this.display.getSaveButton().addClickHandler(new ClickHandler() {   
		      public void onClick(ClickEvent event) {
		    	 display.enableBtnSave(false);
		    	 addProductsSellerList(); 
		      }
		});
		this.display.getGoBackButton().addClickHandler(new ClickHandler() {   
		      public void onClick(ClickEvent event) {
		    	  eventBus.fireEvent(new GoBackEvent(sellerPresenter));
		      }
		});
		this.display.getTable().addRangeChangeHandler(new RangeChangeEvent.Handler() {
	        @Override
	        public void onRangeChange(RangeChangeEvent event) {
	        	doChangeRange();
	    }});	
	}
	

	protected void addProductsSellerList() {
		final Set<ProductDTO> products = display.getSelectionModel().getSelectedSet();
		Iterator<ProductDTO> iterator = products.iterator();
		final ArrayList<Long> codePSelected = new ArrayList<Long>();
		while(iterator.hasNext()){
			codePSelected.add(iterator.next().getCode());
		}
		/*if((codeProducts.containsAll(codePSelected))){
			display.enableBtnSave(true);
			return;
		}
		else{*/
			
			display.showBusyIndicator();
			new RPCCall<Void>(){
				@Override
				public void onFailure(Throwable caught) {
					display.hideBusyIndicator();
					Window.alert(CloudMobile.constants.eAddListProduct());
					display.enableBtnSave(true);
				}
				@Override
				public void onSuccess(Void result) {
					display.hideBusyIndicator();
					display.enableBtnSave(true);
				}
				@Override
				protected void callService(AsyncCallback<Void> cb) {
					productService.addProductsSellerList(userA.getName(),codePSelected,seller.getUserName(), cb);
				}
			}.retry(3);
		
	}
	private void doChangeRange() {
		populateProductsList();
	}
	
	private void populateProductsList() {
		rangeStart = display.getTable().getVisibleRange().getStart();
	    display.showBusyIndicator();
	    pageNum = display.getPage();
		try{
			pageCursor = cursors.get(pageNum);
		}
		catch(Exception e){
			pageCursor = null;
		}
		new RPCCall<ResultDTO<ProductDTO>>(){
			@Override
			public void onFailure(Throwable caught) {
				display.hideBusyIndicator();
				Window.alert(CloudMobile.constants.eGetProducts());	
			}
			@Override
			public void onSuccess(ResultDTO<ProductDTO> result) {
				display.hideBusyIndicator();
				try{
					pageCursor = cursors.get(pageNum+1);
				}
				catch(Exception e){
					pageCursor = null;
				}
				if(result.getList() != null){
					if(pageCursor == null)
						cursors.add(result.getCursorString());
					for(int i=0;i< result.getSelectedIDs().size();i++){
						Long a = result.getSelectedIDs().get(i);
						for(int j=0;j<result.getList().size();j++){
							if(a.equals(result.getList().get(j).getCode()))
								display.getSelectionModel().setSelected(result.getList().get(j), true);
						}
					}
				display.getTable().setRowData(rangeStart, result.getList());
				}
			}
			@Override
			protected void callService(AsyncCallback<ResultDTO<ProductDTO>> cb) {
				productService.getProductsSeller(pageCursor,pageSize,userA.getName(),seller.getUserName(),cb);
			}
		}.retry(3);
		
	}
	@Override
	public void go(HasWidgets container) {
		container.clear();
	    container.add(display.asWidget());	 
	}
	
	public void updateRowCount(){
		productService.getProductsCount(userA.getName(),new AsyncCallback<Integer>(){
			@Override
			public void onFailure(Throwable caught) {	
				Window.alert(CloudMobile.constants.eGetCountProducts());	
			}
			@Override
			public void onSuccess(Integer result) {
				display.getTable().setRowCount(result,true);
				if(result>0)
					populateProductsList();
			}});
	}
}
